#include "mainwindow.h"
#include "ui_mainwindow.h"



MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // OpenSerialPorts("com3");
    // refreshSerialPorts();
    openSavedPort();
    connect(ui->BaudRate, &QLineEdit::editingFinished, this, &MainWindow::SetBaudRate);
    // connect(ui->RSSI, &QLineEdit::editingFinished, this, &MainWindow::on_RSSI_returnPressed);
    DefaultPattern();
    // 设置背景图片
    // QPixmap bkgnd(":/Users/10007754/Desktop/Works/gitee/Remotecontrol/Remotecontrol/images/background.jpg");
    // bkgnd = bkgnd.scaled(this->size(), Qt::IgnoreAspectRatio);
    // QPalette palette;
    // palette.setBrush(QPalette::Window, bkgnd);
    // this->setPalette(palette);


    on_RSSI_returnPressed();
    SetBaudRate();


    timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, &MainWindow::handleTimeout);
    // connect(this, &MainWindow::returnToReadData, this, &MainWindow::ReceiveDataTest); // returnToReadData 信号接收 执行start_to_work




}

MainWindow::~MainWindow()
{
    delete ui;
}
// void MainWindow::saveCurrentState()
// {
//     // 保存窗口状态
//     QByteArray windowState = saveState();
//     QSettings settings("YourCompany", "YourApp");
//     settings.setValue("WindowState", windowState);
// }
// void MainWindow::startNewInstance()
// {
//     QProcess process;
//     connect(&process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &MainWindow::onNewInstanceFinished);
//     process.start(QApplication::applicationFilePath()); // 启动新的实例
// }

// void MainWindow::onNewInstanceFinished(int exitCode, QProcess::ExitStatus exitStatus)
// {
//     qApp->quit(); // 关闭当前实例
// }
void MainWindow::handleTimeout()
{

        // saveCurrentState();
        qDebug() << "超时错误";
        ui->label->setText("时间到 \n若存在红色或灰色则为不通过");
        // delete dataToRelease;
        // dataToRelease = nullptr;
        timer->stop();
        // Within20s = false;
        // entertest = false;
        temp=false;
        data.clear();
        dataList.clear();
        datatemp.clear();
        lastData.clear();
        comparisonCount=1;

        // if(snumer==5)
        // {

        //     // 保存当前状态
        //     saveCurrentState();

        //     // 启动新实例
        //     startNewInstance();
        // }
        // qDebug() << "SUCCESS"<<SUCCESS;
        // if(SUCCESS>=36)
        // reminder->setStyleSheet("background-color: green;");
        // else
        reminder->setStyleSheet("background-color: red;");
        // SUCCESS=0;




}


// 从配置文件中读取保存的串口信息，并连接该串口
void MainWindow::openSavedPort()
{
    QSettings settings("MyCompany", "MyApp");
    lastSelectedPort = settings.value("lastSelectedPort").toString();
    // 从配置文件中读取 SaveRSSI 和 SaveBaudRate 的值
    SaveRSSI = settings.value("SaveRSSI").toString();
    SaveBaudRate = settings.value("SaveBaudRate").toInt();
    qDebug() << "lastSelectedPort:"<<lastSelectedPort;
    if (!lastSelectedPort.isEmpty())
    {
        OpenSerialPorts(lastSelectedPort); // 使用保存的串口信息直接连接串口
        ui->comboBox->addItem(lastSelectedPort);
        availableports();
        qDebug() << "Opening saved port: " << lastSelectedPort;

    }
    else
    {
        refreshSerialPorts();
        qDebug() << "No saved port available.";
    }

}
void MainWindow::closeEvent(QCloseEvent *event)
{
    QSettings settings("MyCompany", "MyApp");
    settings.setValue("SaveRSSI", SaveRSSI);
    settings.setValue("SaveBaudRate", SaveBaudRate);
    settings.setValue("lastSelectedPort", lastSelectedPort);
    QMainWindow::closeEvent(event);
}

//连接串口
void MainWindow::OpenSerialPorts(const QString &portName)
{
    if(SaveBaudRate==0||SaveBaudRate== NULL)SaveBaudRate=QSerialPort::Baud115200;
    qDebug() << "SaveBaudRate"<<SaveBaudRate ;

    m_serial.setPortName(portName);//获取当前串口名
    //连接
    m_serial.open(QIODevice::ReadWrite);//读写模式
    if(m_serial.isOpen())
    {
        qDebug() << "连接成功 "<<portName ;
    ui->label->setText("连接成功 \n请按【照明按钮】开始测试\n");
    m_serial.setBaudRate(SaveBaudRate);//115200
    m_serial.setDataBits(QSerialPort::Data8); //数据位
    m_serial.setStopBits(QSerialPort::OneStop);//停止位
    lastSelectedPort=portName;                //将连接的串口信息记录
    QObject::connect(&m_serial, &QSerialPort::readyRead, this, &MainWindow::start_to_work); //开始接收串口数据
    }
    else
    {
    qDebug() << "连接失败" ;
    ui->label->setText("连接失败");
}
}
// 获取可用的串口信息
void MainWindow::availableports()
{
    // 获取可用的串口信息
    QList<QSerialPortInfo> ports = QSerialPortInfo::availablePorts();

    // 遍历可用串口，将其添加到comboBox中（确保不重复添加）
    foreach(const QSerialPortInfo &portInfo, ports)
    {
        // 获取串口名字
        QString portName = portInfo.portName();

        // 检查该串口是否已经存在于comboBox中
        bool alreadyAdded = false;
        for (int i = 0; i < ui->comboBox->count(); ++i)
        {
            if (ui->comboBox->itemText(i) == portName)
            {
                alreadyAdded = true;
                break;
            }
        }
        // 如果该串口不存在于comboBox中，则添加
        if (!alreadyAdded)
        {
            ui->comboBox->addItem(portName);
        }
    }
}
//获取串口信息 添加到comboBox中
void MainWindow::refreshSerialPorts()
{
    // 清空comboBox中的项
    ui->comboBox->clear();
    availableports();
    on_comboBox_activated();
}

void MainWindow::SetBaudRate() {
    if(SaveBaudRate == 0) {
        SaveBaudRate = 115200;
        ui->BaudRate->setPlaceholderText("波特率:115200");
    } else {
        QString baudRateStr = QString::number(SaveBaudRate);
        ui->BaudRate->setPlaceholderText(QString("波特率 %1").arg(baudRateStr));
    }

    inputBaudRate = ui->BaudRate->text().toInt();
    if(inputBaudRate != 0) {
        SaveBaudRate = inputBaudRate;
    }
    qDebug() << "波特率设置为:" << SaveBaudRate;
}

void MainWindow::RightComp(QFrame* frame )
{
    frame->setFixedSize(GEAR_SIZE, GEAR_SIZE);
    frame->setStyleSheet("background-color: green; border-radius: 42px;");
}

void MainWindow::ErrorComp(QFrame* frame)
{
    frame->setFixedSize(GEAR_SIZE, GEAR_SIZE);
    frame->setStyleSheet("background-color: red; border-radius: 42px;");
    // frame->setStyleSheet("background-color: red;");
}
void MainWindow::NumRightComp(QFrame* frame )
{
    frame->setFixedSize(SECTOR_SIZE, SECTOR_SIZE);
    frame->setStyleSheet("background-color: green; border-radius: 25px;");
}
void MainWindow::NumErrorComp(QFrame* frame)
{
    frame->setFixedSize(SECTOR_SIZE, SECTOR_SIZE);
    frame->setStyleSheet("background-color: red; border-radius: 25px;");
    // frame->setStyleSheet("background-color: red;");
}
void MainWindow::AddLabelToFrame(QFrame* frame, const QString& labelText)
{
    QLabel* label = new QLabel(labelText, frame);
    label->setAlignment(Qt::AlignCenter);
    // label->setGeometry(0, 0, frame->width(), 20); // 将标签放置在 QFrame 的顶部
    // 获取QFrame和标签的大小
    int frameWidth = frame->width();
    int frameHeight = frame->height();
    int labelWidth = label->width()-15;
    int labelHeight = label->height()-18;

    // 计算标签应该放置的位置
    int x = (frameWidth - labelWidth) / 2;  // 水平方向居中
    int y = (frameHeight - labelHeight) / 2;  // 垂直方向居中

    // 设置标签的位置
    label->setGeometry(x, y, labelWidth, labelHeight);
}

void MainWindow::SetGearColors()
{
    QFrame* gears[] = {Lighting, ambient,
                       await, baby, dimming,
                       time, gear1, gear2,
                       gear3, gear4, gear5,
                       gear6, gearstop};
    const int numGears = sizeof(gears) / sizeof(gears[0]);

    // 设置所有控件的背景色为灰色
    for (int i = 0; i < numGears; ++i)
    {
        // gears[i]->setStyleSheet("background-color: grey;");
        if(i<6||i==12)
        {
            gears[i]->setStyleSheet("background-color: grey;border-radius: 42px;");
        }
        else gears[i]->setStyleSheet("background-color: grey;border-radius: 23px;");
    }
    reminder->setStyleSheet("background-color: rgba(0, 0, 0, 0);");
}
void MainWindow::DefaultPattern()
{
    Lighting = ui->Lighting;  // 照明
    ambient = ui->ambient;     // 氛围灯
    await = ui->await;         // 待机
    baby = ui->baby;           // 宝宝风
    dimming = ui->dimming;     // 调光
    time = ui->time;           // 定时
    gear1 = ui->gear1;
    gear2 = ui->gear2;
    gear3 = ui->gear3;
    gear4 = ui->gear4;
    gear5 = ui->gear5;
    gear6 = ui->gear6;
    gearstop = ui->stop;
    reminder = ui->reminder;

    QFrame* gears[] = {Lighting, ambient,
                       await, baby, dimming,
                       time, gear1, gear2,
                       gear3, gear4, gear5,
                       gear6, gearstop};
    QString gearLabels[] = {"照明", "氛围灯", "待机", "宝宝风",
                            "调光", "定时", "1档位", "2档位",
                            "3档位", "4档位", "5档位", "6档位", "停止"};
    const int numGears = sizeof(gears) / sizeof(gears[0]);

    for (int i = 0; i < numGears; ++i)
    {
        QFrame* currentGear = gears[i];
        const QString& currentLabel = gearLabels[i];

        if (i < 6 || i == 12) // 对前面六个控件设置相同样式和大小
        {
            currentGear->setFixedSize(GEAR_SIZE, GEAR_SIZE);
            currentGear->setStyleSheet("background-color: grey; border-radius: 42px;");
        }
        else
        {
            currentGear->setFixedSize(SECTOR_SIZE, SECTOR_SIZE); // 设置不同大小
            currentGear->setStyleSheet("background-color: grey; border-radius: 23px;"); // 设置不同样式
        }

        AddLabelToFrame(currentGear, currentLabel);
    }
    reminder->setStyleSheet("background-color: rgba(0, 0, 0, 0);");

}
// void MainWindow::OriginalCode()
// {
//     // 将十六进制字符串转换为无符号整数值
//     unsigned int thirdSecondValue = thirdsecondByteArray.toUInt(nullptr, 16);
//     unsigned int fourSecondValue = foursecondByteArray.toUInt(nullptr, 16);
//     // qDebug() << "thirdSecondValue" << thirdSecondValue;
//     // qDebug() << "fourSecondValue" << fourSecondValue;

//     // 合成补码
//     int complement = (thirdSecondValue << 8) | fourSecondValue;
//     // qDebug() << "合成补码为：" << complement;

//         // int finalValue;

//     // 处理补码为负数的情况
//     if (complement & 0x8000) {
//         // 最高位为1，表示为负数
//         // 补码取反加一
//         int negComplement = (~complement + 1) & 0xFFFF; // 使用16位掩码
//         finalValue = -negComplement;
//     } else {
//         // 最高位为0，表示为正数，原码即为补码本身
//         finalValue = complement;
//     }

//     // qDebug() << "合成原码为：" << finalValue;
// }

bool MainWindow::CompareValues(QByteArray currentValue)
{
    static QReadWriteLock rwLock;
    static QByteArray previousValue;
    rwLock.lockForWrite(); // 写锁

    bool result = false;

    if (previousValue.isEmpty())
    {
        previousValue = currentValue;
    }
    else
    {
        if (previousValue == currentValue)
        {
            result = true;
        }
        previousValue = currentValue;
    }

    rwLock.unlock(); // 解锁

    return result;
}

void MainWindow::EstimateData()
{
    // qDebug() << "data数据:"<<data;
    static QMutex mutex; // 互斥锁
    mutex.lock();
    // static int num=0;
    bool  rssiflag=false;
    finalValue=static_cast<int>(thirdsecondByteArray.toUInt(nullptr, 16));
    bool coptemp = CompareValues(foursecondByteArray);
    // qDebug() << "次数是 ："<< static_cast<int>(foursecondByteArray.toUInt(nullptr, 16));;
    // bool judgeStart = CompareValues(secondByteArray);
    qDebug() << "coptemp的值是"<<coptemp;
    if (finalValue < SaveRSSI.toInt() )
    {
        rssiflag=true;

    }
    else
    {
        qDebug() << "不满足rrsi";
        // ProcessFrame(on);
    }

        if(temp)
        {
            // qDebug() << "判断temp";
            // num=0;
            if (lastData.mid(2, 2) == secondByteArray)
            {
                // qDebug() << "判断temp 后的 次数是 ："<< static_cast<int>(foursecondByteArray.toUInt(nullptr, 16));; //次数没有发生改变
                // qDebug() << "进入判断2"<<lastData.mid(2, 2)<<secondByteArray;

                if (coptemp)
                {
                    qDebug() << "进入判断3 是同一个按键";
                    comparisonCount++;
                    secondByteComp = secondByteArray;
                    AllcomparisonCount++;
                    // QThread::msleep(10); // 添加延时

                }
                else
                {
                    if (comparisonCount >= 3 && rssiflag)
                    qDebug() << "判断3 ：再次按下";
                    comparisonCount = 1;
                    AllcomparisonCount = 1;
                    // QThread::msleep(2); // 添加延时

                }

            }
            else
            {
                AllcomparisonCount=AllcomparisonCount/2;
                comparisonCount=comparisonCount/2;
                qDebug() << "进入判断4： 切换按键";
                lastData = data;
                secondByteComp = secondByteArray;
                if (comparisonCount >= 3 && rssiflag)
                {
                    ProcessFrame(yes);
                    // SUCCESS++;
                }
                else
                {
                    ProcessFrame(on);
                }
                qDebug() << "重置计数";
                comparisonCount = 1;
                AllcomparisonCount = 1;
                // QThread::msleep(2);
            }
        }


    if (comparisonCount >= 3 && rssiflag)
    {
        ProcessFrame(yes);
        // SUCCESS++;
    }
    else
    {
        ProcessFrame(on);
    }
    // qDebug() << "1111111111111111111111111111111SUCCESS"<<SUCCESS;
    qDebug() << "comparisonCount" << comparisonCount;
    qDebug() << "AllcomparisonCount" << AllcomparisonCount;
    mutex.unlock();
}
void MainWindow::ReceiveDataTest()
{
    if(data.isEmpty()) {
        // 如果 data 为 NULL，则不进行任何操作
    } else {
        if (data.startsWith(frameHeader) && data.endsWith(frameTail)) {
            // qDebug() << "data 以 frameHeader 开头并且以 frameTail 结尾";
            // qDebug() << "data"<<data;
            if (data.length() == 10 ) {
                secondByteArray = data.mid(2, 2); // 提取第二个字节的 QByteArray
                // qDebug() << "提取出的第二个 QByteArray 是：" << secondByteArray;
                thirdsecondByteArray = data.mid(4, 2); // 提取出的第三个 QByteArray 高八位  第八位 高八位删除
                // qDebug() << "低八位 是：" << thirdsecondByteArray;
                foursecondByteArray = data.mid(6, 2); // 提取出的第三个 QByteArray 低八位   次数
                 // qDebug() << "次数 是：" << foursecondByteArray;
                // fivesecondByteArray = data.mid(8, 2);
                // qDebug() << "fivesecondByteArray 是：" << fivesecondByteArray;
                // OriginalCode();

                EstimateData();
            }
            else {
                qDebug() << "接收到的数据有问题";
                // readData();

            }
        } else {
            qDebug() << "data 不符合条件";
        }
    }


}
// 判断后提示以为最多的为准进行展示
void MainWindow::ProcessFrame(int yeson)
{
    QMap<QByteArray, QFrame*> frameMap  = {
        {Onegear, gear1},
        {Twogear, gear2},
        {Threegear, gear3},
        {Fourgear, gear4},
        {Fivegear, gear5},
        {Sixgear, gear6},
        {Stopgear, gearstop},
        {Lightinggear, Lighting},
        {dimminggear,dimming},
        {Timegear, time},
        {Babygear, baby},
        {Ambientgear, ambient},
        {Awaitgear, await}
    };

    auto it = frameMap.find(secondByteComp);
    if (it != frameMap.end()) {
        QFrame* frame = it.value();
        if(yeson==yes)
        {
          if (frame == gear1 || frame == gear2 || frame == gear3 || frame == gear4 || frame == gear5 || frame == gear6)
                NumRightComp(frame);
          else RightComp(frame);

         }
        else if(yeson==on)
        {
            if (frame == gear1 || frame == gear2 || frame == gear3 || frame == gear4 || frame == gear5 || frame == gear6)
                NumErrorComp(frame);
            else ErrorComp(frame);
        }
    }
}
// void MainWindow::readData()
// {
//     static QByteArray buffer; // 缓冲区，保存接收到的字符
//     data = m_serial.readAll();
//     qDebug() << "接收到的数据：" << data;
//     // 去除data中的回车换行符
//     data = data.simplified();

//     // 去除startdata和data中的空格，统一格式
//     startdata = startdata.simplified().replace(" ", "");
//     data = data.replace(" ", "");

//     // std::string hexData = data.toStdString();
//     // std::string plainText = hexStringToPlainText(hexData);
//     // qDebug() << "接收到的plainText数据：" << plainText;
//     qDebug() << "接收到的buffer数据：" << buffer;
//     checkData(); // 调用新的函数进行数据判断和处理


// }

void MainWindow::start_to_work()
{
    // dataLock.lockForWrite(); // 写锁
    readData();
    processNextData();

    // dataLock.unlock(); // 解锁
}

void MainWindow::readData()
{


    static QByteArray buffer; // 缓冲区，保存接收到的字符
    datatemp = m_serial.readAll();

    QString hexString = QString::fromLatin1(datatemp.toHex().toUpper()).remove("\\X");

    if (hexString.contains(frameHeader)) {
        buffer.clear(); // 清空缓冲区
    }

    buffer.append(datatemp);

    if (buffer.size() == 5 && hexString.contains(frameTail)) {
        // QThread::msleep(10); // 暂停5毫秒
        QString HexString = QString::fromLatin1(buffer.toHex().toUpper()).remove("\\X");
        QByteArray processedData = HexString.toLatin1();

        // data = processedData;
        reminder->setStyleSheet("background-color: rgba(0, 0, 0, 0);");
        ui->label->clear();
        // ui->label->setText(QString("判断的数据：%1").arg(processedData));
        buffer.clear(); // 清空缓冲区

        // qDebug() << "processedData" << processedData;

        // 将processedData添加到列表中
        dataList.append(processedData);

    }
    // if (buffer.isEmpty()) {
    //     qDebug() << "buffer has been cleared.";
    // }
    // int i = 0;
    // for (const auto& data : dataList)
    // {
    //     qDebug() << QString("Data: %1 %2").arg(i).arg(data);
    //     i++;
    // }

}
void MainWindow::getstatic(const QByteArray &data)
{
    QString dataStr = QString::fromLatin1(data);
    QRegularExpression rx("AA08[0-9A-Fa-f]{4}BB"); // 匹配格式为AA08xxxxBB的字符串，其中x为任意十六进制字符
    if (rx.match(dataStr).hasMatch())
    {
        temp=true;
        // temp=true;
        // if(secondByteArray== "08")
        // {
        //     temp=true;
        //     // snumer++;
            // DefaultPattern();
        SetGearColors();
        timer->stop();
        timer->start(20000); // 开始定时，20秒后超时 20000
        reminder->setStyleSheet("background-color: green;");
        ui->label->setText(("倒计时20s开始"));
        //     // emit returnToReadData();
        // }
        // emit returnToReadData();
    }
}
void MainWindow::processNextData()
{

    for (int i = currentIndex; i < dataList.size(); i++) {
        QByteArray currentData = dataList.at(i);
        data = currentData;
        getstatic(data);
        qDebug() << "currentData " << i << ": " << currentData;
        ReceiveDataTest();

    }
    dataList.clear();
    datatemp.clear();
    // if (dataList.isEmpty()) {
    //     qDebug() << "dataList has been cleared.";
    // }

    // if (datatemp.isEmpty()) {
    //     qDebug() << "datatemp has been cleared.";
    // }
}

// void MainWindow::checkData()
// {
//     static QMutex mutex;

//     // 在需要锁定线程的地方加锁
//     mutex.lock();
//     if (startdata == data) {
//         ui->label->clear();
//         // dataList.clear();
//         comparisonCount = 1; // 重置计数
//         AllcomparisonCount=1;
//         DefaultPattern();
//         // qDebug() << "data" << data;
//         qDebug() << "启动测试命令";
//          // QThread::msleep(20);
//         entertest = true;
//         // Within20s = !Within20s;
//         Within20s = true ;
//         timer->start(20000); // 开始定时，20秒后超时 20000
//         ui->label->setText(("倒计时20s开始"));

//     }
//     else if (entertest && startdata != data) {
//         ReceiveDataTest();
//         // qDebug() << "entertest为真";
//     }
//     else {
//         // 如果不满足上述条件，重新设置 Within20s 为 false
//         Within20s = false;
//     }
//         mutex.unlock();
// }
void MainWindow::on_RSSI_returnPressed()
{
    qDebug() << "SaveRSSI" << SaveRSSI;
    if (!SaveRSSI.isEmpty()){
     ui->RSSI->setPlaceholderText(QString("RSSI值: %1").arg(SaveRSSI));
    }
    else {
        ui->RSSI->setPlaceholderText("RSSI值,默认为0");
    }

    // 获取输入的RSSI并更新SaveRSSI
    QString inputRSSI = ui->RSSI->text();
    if (!inputRSSI.isEmpty()) {
        SaveRSSI = inputRSSI;
    }

    qDebug() << "inputRSSI输入为" << SaveRSSI;
}


void MainWindow::on_comboBox_activated()
{
    QString portName = ui->comboBox->currentText(); // 获取选定的串口名称
    m_serial.close();
    OpenSerialPorts(portName); // 调用OpenSerialPorts函数，并传递选定的串口名称作为参数
    qDebug() << "portName" <<portName;
}

